﻿using AroPl.Addons;
using Newtonsoft.Json.Linq;
using Rocket.Core;
using Rocket.Core.Plugins;
using Rocket.Core.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using Dir = System.IO.Directory;
using Dll = System.Reflection.Assembly;
using Logger = Rocket.Core.Logging.Logger;

namespace AroPl
{
    public class GameLoader : RocketPlugin<Configuration>
    {
        private Dictionary<string, bool> PluginsModifies;

        protected override void Load()
        {
            if (!Dir.Exists(Directory + "/Resources"))
            {
                Dir.CreateDirectory(Directory + "/Resources");
            }
            Logger.Log("[极光·未来] - AroPl - 正在加载支持库...", ConsoleColor.Green);
            Loader.LoadLibraries(Directory);
            PluginsModifies = new Dictionary<string, bool>();
            foreach (PluginModify pluginModify in Configuration.Instance.pluginModifies)
            {
                PluginsModifies.Add(pluginModify.PluginID, pluginModify.Load);
            }
            if (string.IsNullOrEmpty(Configuration.Instance.UserKey))
            {
                Configuration.Instance.UserKey = Guid.NewGuid().ToString();
                Configuration.Save();
                switch (AuroraCloud.RegisterUser(Configuration.Instance.UserKey))
                {
                    case RegisterState.Failed:
                        Logger.Log("[极光·未来] - AroPl - 初始化密钥失败 请重试", ConsoleColor.Yellow);
                        return;
                    case RegisterState.Success:
                        Logger.Log("[极光·未来] - AroPl - 初始化用户密钥 请联系管理员激活", ConsoleColor.Yellow);
                        break;
                }
            }
            if (!Guid.TryParse(Configuration.Instance.UserKey, out Guid key))
            {
                Logger.Log("[极光·未来] - AroPl - 无法验证用户密钥", ConsoleColor.Yellow);
                return;
            }
            Type type = R.Plugins.GetType();
            List<GameObject> plugins = Loader.GetGameEntry(type);
            if (plugins == null)
            {
                Logger.Log("[极光·未来] - AroPl - 无法初始化插件加载接口 请联系管理员", ConsoleColor.Yellow);
                return;
            }
            try
            {
                #region 在线加载
                PluginBack pluginBack = AuroraCloud.LoginUser(Configuration.Instance.UserKey);
                switch (pluginBack.loginState)
                {
                    case LoginState.Failed:
                        Logger.Log("[极光·未来] - AroPl - 初始化密钥遇到错误 请重试", ConsoleColor.Yellow);
                        return;
                    case LoginState.Banned:
                        Logger.Log("[极光·未来] - AroPl - 用户密钥已被封禁 请联系管理员", ConsoleColor.Yellow);
                        return;
                }
                foreach (JToken jToken in pluginBack.result.Children())
                {
                    if ((jToken as JProperty).Name == "ResultCode")
                    {
                        continue;
                    }
                    string[] values = (jToken as JProperty).Value.ToString().Split('|');
                    if (!PluginsModifies.ContainsKey((jToken as JProperty).Name))
                    {
                        Configuration.Instance.pluginModifies.Add(new PluginModify() { PluginID = (jToken as JProperty).Name, Load = true });
                        Configuration.Save();
                    }
                    else if (!PluginsModifies[(jToken as JProperty).Name])
                    {
                        continue;
                    }
                    if (!File.Exists(Directory + $"/Resources/{(jToken as JProperty).Name}.data") || FileAuth.GetMD5HashFromFile(Directory + $"/Resources/{(jToken as JProperty).Name}.data")
                        != values[2])
                    {
                        if (values[3] == "drm")
                        {
                            AuroraCloud.GetDRMFile(this.Directory, (jToken as JProperty).Name, values[1]);
                        }
                        AuroraCloud.GetNoDRMFile(this.Directory, (jToken as JProperty).Name);
                    }
                    PluginLoad(type, plugins, ((jToken as JProperty).Name), values[1]);
                }
                #endregion
            }
            catch
            {
                #region 离线加载
                Logger.Log("[极光·未来] - AroPl - 无法连接到极光服务器 正在以离线模式加载", ConsoleColor.Yellow);
                List<string> files = new List<string>(System.IO.Directory.GetFiles(this.Directory + @"\Resources"));
                foreach (string file in files)
                {
                    if (file.EndsWith(".drm"))
                    {
                        if (files.Contains(file.Replace(".drm", "-drm.data")))
                        {
                            JObject jObject = JObject.Parse(Encoding.UTF8.GetString(AESEncryption.AesDecryptor(File.ReadAllBytes(file),
                                FileAuth.GetMD5HashFromFile(file.Replace(".drm", "-drm.data")))));
                            if (DateTime.Now > DateTime.Parse(jObject["OutdateTime"].ToString()))
                            {
                                Logger.Log($"[极光·未来] - AroPl - DRM证书{file}已过期!", ConsoleColor.Red);
                                continue;
                            }
                            PluginLoadWithDRM(type, plugins, file.Replace(".drm", "-drm.data"), jObject["DRMKey"].ToString());
                        }
                    }
                }
                #endregion
            }
            Logger.Log("[极光·未来] - 插件前置 - 已加载", ConsoleColor.Green);
        }

        public void PluginLoad(Type loadtype, List<GameObject> loadentry, string Plugin, string loadkey)
        {
            Dll a = Dll.Load(AESEncryption.AesDecryptor(File.ReadAllBytes(Directory + $"/Resources/{Plugin}.data"), loadkey));
            foreach (Type type1 in RocketHelper.GetTypesFromInterface(a, "IRocketPlugin"))
            {
                GameObject gameObject = new GameObject(loadtype.Name, new Type[]
                {
                    type1
                });
                UnityEngine.Object.DontDestroyOnLoad(gameObject);
                loadentry.Add(gameObject);
            }
        }

        public void PluginLoadWithDRM(Type loadtype, List<GameObject> loadentry, string Plugin, string DRMKey)
        {
            Dll a = Dll.Load(AESEncryption.AesDecryptor(File.ReadAllBytes(Plugin), DRMKey));
            foreach (Type type1 in RocketHelper.GetTypesFromInterface(a, "IRocketPlugin"))
            {
                GameObject gameObject = new GameObject(loadtype.Name, new Type[]
                {
                    type1
                });
                UnityEngine.Object.DontDestroyOnLoad(gameObject);
                loadentry.Add(gameObject);
            }
        }

        protected override void Unload()
        {
            Logger.Log("[极光·未来] - 插件前置 - 已卸载", ConsoleColor.Green);
        }
    }
}
